﻿using System;
using UnityEngine;
using Unity.Entities;
using Jinndev.Modding;

namespace Jinndev.Tile2D {

    /// <summary>
    /// 2D的瓷砖，可以是多个tile组成一个物体
    /// </summary>
    public struct Tile : IComponentData {

        #region static
        public static readonly Tile Empty = new Tile { cfgId = Config.EmptyID };

        public static Tile CreateMain(Guid guid, Int2 index, int direction, RenderConfig renderConfig) {
            Tile tile = new Tile {
                guid = guid,
                index = index,

                cfgId = renderConfig.Id,
                direction = direction,

                padding = false,
                startIndex = index,
            };
            tile.Setup(renderConfig);
            return tile;
        }

        public static Tile CreatePadding(Int2 index, int direction, RenderConfig renderConfig, Int2 mainIndex) {
            Tile tile = new Tile {
                guid = default,
                index = index,

                direction = direction,

                padding = true,
                startIndex = mainIndex,
            };
            tile.Setup(renderConfig);
            return tile;
        }
        #endregion




        public Guid guid;
        public Int2 index;      // 当前坐标

        public int cfgId;           // 配置id
        public int direction;       // 方向

        public bool padding;    // 是否是填充数据
        public Int2 startIndex; // 填充数据的起始坐标，padding=true时代表起始坐标，padding=false时代表当前坐标

        public Int2 realDimension;  // 实际方向的维度大小
        //public Float2 realPivot;    // 实际方向的轴心
        //public Float2 realRenderSize;
        //public Float2 anchor;


        /// <summary>
        /// 是否是空白
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty() {
            return cfgId == Config.EmptyID;
        }

        /// <summary>
        /// 是否是实体，而非填充或空白
        /// </summary>
        /// <returns></returns>
        public bool IsMain() {
            return !IsEmpty() && !padding;
        }

        public bool IsPadding() {
            return padding;
        }

        public void Setup(RenderConfig renderConfig) { 
            cfgId = renderConfig.Id;
            realDimension = renderConfig.GetRealDimension(direction);
            //realPivot = renderConfig.GetRealPivot(direction);
            //realRenderSize = renderConfig.GetRealRenderSize(direction);
            //anchor = renderConfig.anchor;
        }

        /// <summary>
        /// index是否在此Tile范围内
        /// </summary>
        public bool IsInRange(Int2 index) {
            return index.x >= startIndex.x && index.x < startIndex.x + realDimension.x
                && index.y >= startIndex.y && index.y < startIndex.y + realDimension.y;
        }

        public static bool operator ==(Tile lhs, Tile rhs) {
            return lhs.Equals(rhs);
        }

        public static bool operator !=(Tile lhs, Tile rhs) {
            return !lhs.Equals(rhs);
        }

        public bool Equals(Tile other) {
            return other.guid == guid
                && other.index == index
                && other.cfgId == cfgId
                && other.direction == direction
                && other.realDimension == realDimension
                && other.padding == padding
                && other.startIndex == startIndex;
        }

        public override bool Equals(object obj) {
            return obj is Tile && Equals((Tile)obj);
        }

        public override int GetHashCode() {
            int hash = 0;
            hash ^= guid.GetHashCode();
            hash ^= index.GetHashCode();
            hash ^= cfgId.GetHashCode();
            hash ^= direction.GetHashCode();
            hash ^= realDimension.GetHashCode();
            hash ^= padding.GetHashCode();
            hash ^= startIndex.GetHashCode();
            return hash;
        }

        public override string ToString() {
            if (padding) {
                return $"Tile(Padding, cfgId:{cfgId}, index(x:{index.x}, y:{index.y}, startIndex(x:{startIndex.x}, y:{startIndex.y})";
            }
            else {
                return $"Tile(Main, cfgId:{cfgId}, index(x:{index.x}, y:{index.y}, startIndex(x:{startIndex.x}, y:{startIndex.y})";
            }
        }

    }

}
